package com.it.smartoldb.util;

import com.it.smartoldb.entity.*;
import com.it.smartoldb.repository.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

/**
 * 数据初始化器
 * 在应用启动时自动初始化测试数据
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class DataInitializer implements CommandLineRunner {

    private final UserRepository userRepository;
    private final ElderlyRepository elderlyRepository;
    private final StaffRepository staffRepository;
    private final HealthRecordRepository healthRecordRepository;
    private final AppointmentRepository appointmentRepository;

    private final Random random = new Random();

    @Override
    @Transactional
    public void run(String... args) throws Exception {
        log.info("开始初始化测试数据...");
        
        // 检查是否已有足够的测试数据，避免重复初始化
        if (userRepository.count() >= 4 && elderlyRepository.count() >= 10 && staffRepository.count() >= 8) {
            log.info("测试数据已存在，跳过初始化");
            return;
        }
        
        try {
            initializeUsers();
            initializeStaff();
            initializeElderly();
            initializeHealthRecords();
            initializeAppointments();
            
            log.info("测试数据初始化完成！");
        } catch (Exception e) {
            log.error("数据初始化失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 初始化用户数据
     */
    private void initializeUsers() {
        log.info("检查用户数据...");
        
        // 检查并创建管理员用户
        if (!userRepository.existsByUsername("admin")) {
            User admin = new User();
            admin.setUsername("admin");
            admin.setPassword("123456");
            admin.setRole("admin");
            admin.setStatus(1);
            admin.setCreatedAt(LocalDateTime.now());
            admin.setUpdatedAt(LocalDateTime.now());
            userRepository.save(admin);
            log.info("创建管理员用户：admin");
        }
        
        // 检查并创建普通用户
        if (!userRepository.existsByUsername("user")) {
            User user = new User();
            user.setUsername("user");
            user.setPassword("123456");
            user.setRole("user");
            user.setStatus(1);
            user.setCreatedAt(LocalDateTime.now());
            user.setUpdatedAt(LocalDateTime.now());
            userRepository.save(user);
            log.info("创建普通用户：user");
        }
        
        // 检查并创建护士用户
        if (!userRepository.existsByUsername("nurse01")) {
            User testUser1 = new User();
            testUser1.setUsername("nurse01");
            testUser1.setPassword("123456");
            testUser1.setRole("staff");
            testUser1.setStatus(1);
            testUser1.setCreatedAt(LocalDateTime.now());
            testUser1.setUpdatedAt(LocalDateTime.now());
            userRepository.save(testUser1);
            log.info("创建护士用户：nurse01");
        }
        
        // 检查并创建医生用户
        if (!userRepository.existsByUsername("doctor01")) {
            User testUser2 = new User();
            testUser2.setUsername("doctor01");
            testUser2.setPassword("123456");
            testUser2.setRole("staff");
            testUser2.setStatus(1);
            testUser2.setCreatedAt(LocalDateTime.now());
            testUser2.setUpdatedAt(LocalDateTime.now());
            userRepository.save(testUser2);
            log.info("创建医生用户：doctor01");
        }
        
        log.info("用户数据检查完成，当前用户总数：{}", userRepository.count());
    }

    /**
     * 初始化员工数据
     */
    private void initializeStaff() {
        if (staffRepository.count() <= 1) {
            log.info("初始化员工数据...");
            
            List<Staff> staffList = Arrays.asList(
                createStaff("张医生", "医生", "M", 35, "主治医师", "内科、心血管", "执业医师证", 8),
                createStaff("李护士", "护士", "F", 28, "主管护士", "护理、急救", "护士执业证", 5),
                createStaff("王康复师", "康复师", "M", 32, "康复治疗师", "物理治疗、康复训练", "康复治疗师证", 6),
                createStaff("赵营养师", "营养师", "F", 30, "营养师", "营养配餐、健康指导", "营养师证", 4),
                createStaff("陈护工", "护工", "F", 45, "高级护工", "生活护理、陪护", "护工证", 10),
                createStaff("刘心理师", "心理咨询师", "F", 38, "心理咨询师", "心理疏导、认知训练", "心理咨询师证", 7),
                createStaff("孙药师", "药师", "M", 40, "主管药师", "药物管理、用药指导", "执业药师证", 12),
                createStaff("周社工", "社工", "F", 26, "社会工作师", "社会服务、活动组织", "社会工作师证", 3)
            );
            
            staffRepository.saveAll(staffList);
            log.info("员工数据初始化完成，共{}条", staffList.size());
        }
    }

    /**
     * 初始化老人数据
     */
    private void initializeElderly() {
        if (elderlyRepository.count() <= 1) {
            log.info("初始化老人数据...");
            
            // 获取用户数据用于绑定
            User userUser = userRepository.findByUsername("user").orElse(null);
            User nurse01User = userRepository.findByUsername("nurse01").orElse(null);
            User doctor01User = userRepository.findByUsername("doctor01").orElse(null);
            
            List<Elderly> elderlyList = Arrays.asList(
                // 为普通用户绑定一个老人
                createElderlyWithUser("张爷爷", "男", 78, "201", "1", "MEDIUM", "GOOD", "高血压", "降压药", "张小明", "13800138001", userUser != null ? userUser.getId() : null),
                // 为nurse01用户绑定一个老人（可以是家属）
                createElderlyWithUser("李奶奶", "女", 82, "202", "2", "HIGH", "FAIR", "糖尿病、关节炎", "胰岛素、止痛药", "李小红", "13800138002", nurse01User != null ? nurse01User.getId() : null),
                // 为doctor01用户绑定一个老人
                createElderlyWithUser("王大爷", "男", 75, "203", "3", "LOW", "GOOD", "无", "维生素", "王小刚", "13800138003", doctor01User != null ? doctor01User.getId() : null),
                // 其他老人不绑定用户
                createElderlyWithUser("赵奶奶", "女", 85, "204", "4", "HIGH", "POOR", "心脏病、高血压", "心脏药、降压药", "赵小华", "13800138004", null),
                createElderlyWithUser("陈爷爷", "男", 73, "205", "5", "MEDIUM", "GOOD", "胃病", "胃药", "陈小军", "13800138005", null),
                createElderlyWithUser("刘奶奶", "女", 79, "206", "6", "MEDIUM", "FAIR", "骨质疏松", "钙片", "刘小丽", "13800138006", null),
                createElderlyWithUser("孙大爷", "男", 81, "207", "7", "HIGH", "FAIR", "脑梗、高血压", "抗凝药、降压药", "孙小伟", "13800138007", null),
                createElderlyWithUser("周奶奶", "女", 77, "208", "8", "LOW", "GOOD", "轻度认知障碍", "营养药", "周小敏", "13800138008", null),
                createElderlyWithUser("吴爷爷", "男", 83, "209", "9", "MEDIUM", "FAIR", "慢性肾病", "护肾药", "吴小东", "13800138009", null),
                createElderlyWithUser("郑奶奶", "女", 76, "210", "10", "MEDIUM", "GOOD", "轻度贫血", "补血药", "郑小芳", "13800138010", null)
            );
            
            elderlyRepository.saveAll(elderlyList);
            log.info("老人数据初始化完成，共{}条", elderlyList.size());
            
            // 输出绑定信息
            if (userUser != null) {
                log.info("用户 '{}' 绑定老人：张爷爷", userUser.getUsername());
            }
            if (nurse01User != null) {
                log.info("用户 '{}' 绑定老人：李奶奶", nurse01User.getUsername());
            }
            if (doctor01User != null) {
                log.info("用户 '{}' 绑定老人：王大爷", doctor01User.getUsername());
            }
        }
    }

    /**
     * 初始化健康记录数据
     */
    private void initializeHealthRecords() {
        if (healthRecordRepository.count() <= 3) {
            log.info("初始化健康记录数据...");
            
            List<Elderly> elderlyList = elderlyRepository.findAll();
            List<Staff> staffList = staffRepository.findAll();
            
            if (elderlyList.isEmpty() || staffList.isEmpty()) {
                log.warn("缺少老人或员工数据，跳过健康记录初始化");
                return;
            }
            
            for (Elderly elderly : elderlyList) {
                // 为每个老人生成多条健康记录
                createHealthRecordsForElderly(elderly, staffList);
            }
            
            log.info("健康记录数据初始化完成");
        }
    }

    /**
     * 初始化预约数据
     */
    private void initializeAppointments() {
        if (appointmentRepository.count() <= 2) {
            log.info("初始化预约数据...");
            
            List<Elderly> elderlyList = elderlyRepository.findAll();
            List<Staff> staffList = staffRepository.findAll();
            
            if (elderlyList.isEmpty() || staffList.isEmpty()) {
                log.warn("缺少老人或员工数据，跳过预约初始化");
                return;
            }
            
            String[] serviceTypes = {"医疗检查", "康复训练", "营养咨询", "心理疏导", "生活护理", "药物管理", "健康体检", "专科会诊"};
            Appointment.AppointmentStatus[] statuses = {Appointment.AppointmentStatus.PENDING, Appointment.AppointmentStatus.CONFIRMED, Appointment.AppointmentStatus.IN_PROGRESS, Appointment.AppointmentStatus.COMPLETED, Appointment.AppointmentStatus.CANCELLED};
            Appointment.Priority[] priorities = {Appointment.Priority.LOW, Appointment.Priority.NORMAL, Appointment.Priority.HIGH, Appointment.Priority.URGENT};
            
            for (int i = 0; i < 20; i++) {
                Appointment appointment = new Appointment();
                appointment.setElderlyId(elderlyList.get(random.nextInt(elderlyList.size())).getId());
                appointment.setStaffId(staffList.get(random.nextInt(staffList.size())).getId());
                appointment.setServiceType(serviceTypes[random.nextInt(serviceTypes.length)]);
                appointment.setStatus(statuses[random.nextInt(statuses.length)]);
                appointment.setPriority(priorities[random.nextInt(priorities.length)]);
                appointment.setAppointmentTime(LocalDateTime.now().plusDays(random.nextInt(30) - 15));
                appointment.setEndTime(appointment.getAppointmentTime().plusHours(1 + random.nextInt(3)));
                appointment.setServiceAddress("养老院" + (random.nextInt(3) + 1) + "楼");
                appointment.setBookerName("家属" + (i + 1));
                appointment.setBookerPhone("138" + String.format("%08d", random.nextInt(100000000)));
                appointment.setFee(new BigDecimal(50 + random.nextInt(200)));
                appointment.setNotes("预约备注" + (i + 1));
                appointment.setCreatedAt(LocalDateTime.now());
                appointment.setUpdatedAt(LocalDateTime.now());
                
                appointmentRepository.save(appointment);
            }
            
            log.info("预约数据初始化完成，共20条");
        }
    }

    /**
     * 创建员工对象
     */
    private Staff createStaff(String name, String position, String gender, int age, String description, 
                             String skills, String certificates, int experience) {
        Staff staff = new Staff();
        staff.setName(name);
        staff.setPosition(position);
        staff.setGender(gender);
        staff.setAge(age);
        staff.setDescription(description);
        staff.setSkills(skills);
        staff.setCertificates(certificates);
        staff.setWorkExperience(experience);
        staff.setPhone("138" + String.format("%08d", random.nextInt(100000000)));
        staff.setEmail(name.toLowerCase() + "@smartold.com");
        staff.setIdCard(generateIdCard());
        staff.setHireDate(LocalDate.now().minusYears(experience).plusMonths(random.nextInt(12)));
        staff.setSalary(new BigDecimal(4000 + random.nextInt(6000)));
        staff.setStatus(Staff.StaffStatus.ACTIVE);
        staff.setAvatarUrl("https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png");
        staff.setCreatedAt(LocalDateTime.now());
        staff.setUpdatedAt(LocalDateTime.now());
        return staff;
    }

    /**
     * 创建老人对象（带用户绑定）
     */
    private Elderly createElderlyWithUser(String name, String gender, int age, String roomNumber, String bedNumber,
                                         String careLevel, String healthStatus, String medicalHistory, 
                                         String medications, String emergencyContact, String emergencyPhone, Long userId) {
        Elderly elderly = new Elderly();
        elderly.setUserId(userId); // 绑定用户ID
        elderly.setName(name);
        elderly.setGender(gender);
        elderly.setAge(age);
        elderly.setBirthDate(LocalDate.now().minusYears(age));
        elderly.setRoomNumber(roomNumber);
        elderly.setBedNumber(bedNumber);
        elderly.setCareLevel(careLevel);
        elderly.setHealthStatus(healthStatus);
        elderly.setMedicalHistory(medicalHistory);
        elderly.setMedications(medications);
        elderly.setEmergencyContact(emergencyContact);
        elderly.setEmergencyPhone(emergencyPhone);
        elderly.setEmergencyRelation("子女");
        elderly.setPhone("138" + String.format("%08d", random.nextInt(100000000)));
        elderly.setIdCard(generateIdCard());
        elderly.setAddress("北京市朝阳区" + (random.nextInt(100) + 1) + "号");
        elderly.setAdmissionDate(LocalDate.now().minusMonths(random.nextInt(36)));
        elderly.setStatus("ACTIVE");
        elderly.setAllergies(random.nextBoolean() ? "无" : "海鲜过敏");
        elderly.setRemarks("测试数据");
        elderly.setCreatedAt(LocalDateTime.now());
        elderly.setUpdatedAt(LocalDateTime.now());
        return elderly;
    }

    /**
     * 创建老人对象（保持兼容性）
     */
    private Elderly createElderly(String name, String gender, int age, String roomNumber, String bedNumber,
                                 String careLevel, String healthStatus, String medicalHistory, 
                                 String medications, String emergencyContact, String emergencyPhone) {
        return createElderlyWithUser(name, gender, age, roomNumber, bedNumber, careLevel, healthStatus, 
                                   medicalHistory, medications, emergencyContact, emergencyPhone, null);
    }

    /**
     * 为指定老人创建健康记录
     */
    private void createHealthRecordsForElderly(Elderly elderly, List<Staff> staffList) {
        String[] recordTypes = {"blood_pressure", "temperature", "heart_rate", "blood_sugar", "weight"};
        
        for (int i = 0; i < 5 + random.nextInt(10); i++) {
            HealthRecord record = new HealthRecord();
            record.setElderlyId(elderly.getId());
            record.setRecordedBy(staffList.get(random.nextInt(staffList.size())).getId());
            
            String recordType = recordTypes[random.nextInt(recordTypes.length)];
            record.setRecordType(recordType);
            record.setRecordTime(LocalDateTime.now().minusDays(random.nextInt(30)));
            
            switch (recordType) {
                case "blood_pressure":
                    record.setSystolicPressure(120 + random.nextInt(40));
                    record.setDiastolicPressure(70 + random.nextInt(20));
                    record.setUnit("mmHg");
                    record.setStatus(record.getSystolicPressure() > 140 || record.getDiastolicPressure() > 90 ? "HIGH" : "NORMAL");
                    break;
                case "temperature":
                    record.setValue(new BigDecimal(36.0 + random.nextDouble() * 2));
                    record.setUnit("°C");
                    record.setStatus(record.getValue().doubleValue() > 37.5 ? "HIGH" : "NORMAL");
                    break;
                case "heart_rate":
                    record.setValue(new BigDecimal(60 + random.nextInt(40)));
                    record.setUnit("次/分");
                    record.setStatus(record.getValue().intValue() > 100 ? "HIGH" : "NORMAL");
                    break;
                case "blood_sugar":
                    record.setValue(new BigDecimal(4.0 + random.nextDouble() * 6));
                    record.setUnit("mmol/L");
                    record.setStatus(record.getValue().doubleValue() > 7.0 ? "HIGH" : "NORMAL");
                    break;
                case "weight":
                    record.setValue(new BigDecimal(50 + random.nextInt(30)));
                    record.setUnit("kg");
                    record.setStatus("NORMAL");
                    break;
            }
            
            record.setNotes("自动生成的测试数据");
            if ("HIGH".equals(record.getStatus())) {
                record.setSuggestions("建议关注指标变化，必要时就医");
            }
            record.setCreatedAt(LocalDateTime.now());
            record.setUpdatedAt(LocalDateTime.now());
            
            healthRecordRepository.save(record);
        }
    }

    /**
     * 生成身份证号
     */
    private String generateIdCard() {
        StringBuilder sb = new StringBuilder();
        // 地区码（北京110101）
        sb.append("110101");
        // 出生年月日
        int year = 1930 + random.nextInt(50);
        int month = 1 + random.nextInt(12);
        int day = 1 + random.nextInt(28);
        sb.append(String.format("%04d%02d%02d", year, month, day));
        // 顺序码
        sb.append(String.format("%03d", random.nextInt(1000)));
        // 校验码
        sb.append(random.nextInt(10));
        return sb.toString();
    }
} 